package com.pai4j.pgc.service.community;
import com.pai4j.common.bean.PAIPageResponseBeanUtil;
import com.pai4j.common.enums.CommonStatusEnum;
import com.pai4j.domain.community.vo.request.CCNavControlRequestVO;
import com.pai4j.domain.community.vo.request.CCNavRequestVO;
import com.pai4j.domain.community.vo.response.cc.CTCNavResponseVO;
import com.pai4j.pgc.dao.community.ICCNavDAO;
import com.pai4j.pgc.dao.community.ICCNavPathDAO;
import com.pai4j.pgc.entity.community.CCNavEntity;
import com.pai4j.pgc.entity.community.CCNavPathEntity;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 *
 *
 * @author: CYM-pai
 * @date: 2025/10/27 14:18
 **/
@Service
public class CCNavService {

    @Autowired
    private ICCNavDAO navDAO;
    @Autowired
    private ICCNavPathDAO pathDAO;
    @Autowired
    private CCNavCoreCacheService coreCacheService;
    @Autowired
    private CCNavPathService pathService;

    /***
     * 保存
     * @param vo
     * @param operator
     * @return
     */
    public Long save(CCNavRequestVO vo, String operator) {
        CCNavEntity navEntity = this.convertNavEntity(vo, operator);
        navEntity = navDAO.save(navEntity);
        Long ccid = pathDAO.findAllById(navEntity.getPathId()).getCcId();
        // 刷新全站导航缓存
        coreCacheService.refreshClientNavCache(ccid);
        return navEntity.getId();
    }

    /***
     * 刷新核心导航
     * @param vo
     * @param operator
     */
    public void updateStatus(CCNavControlRequestVO vo, String operator) {
        CCNavEntity navEntity = navDAO.findAllById(vo.getId());
        Assert.isTrue(navEntity != null, "修改失败:导航不存在!");
        navEntity.setStatus(vo.getStatus());
        navEntity.setUpdateBy(operator);
        navEntity.setUpdateDate(new Date());
        navDAO.save(navEntity);
        // 刷新用户测全站导航
        Long ccid = pathDAO.findAllById(navEntity.getPathId()).getCcId();
        coreCacheService.refreshClientNavCache(ccid);
    }

    /***
     * 管理列表查询
     * @param pathId
     * @param keyword
     * @param pageNo
     * @param pageSize
     * @return
     */
    public PAIPageResponseBeanUtil<List<CTCNavResponseVO>> list(Long pathId, String keyword, List<String> statusList,
                                                                Integer pageNo, Integer pageSize, String userId) {
        // 构建排序规则
        Sort sort = buildQueryOrderCondition();
        // 分页条件
        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);
        // 查询条件
        Specification<CCNavEntity> specification = new Specification<CCNavEntity>() {
            @Override
            public Predicate toPredicate(Root<CCNavEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (pathId != null) {
                    predicates.add(criteriaBuilder.equal(root.get("pathId").as(Long.class), pathId));
                }
                if (!StringUtils.isEmpty(userId)) {
                    predicates.add(criteriaBuilder.equal(root.get("createBy").as(String.class), userId));
                }
                if (!StringUtils.isEmpty(keyword)) {
                    predicates.add(criteriaBuilder.like(root.get("name").as(String.class), "%" + keyword + "%"));
                }
                if (!CollectionUtils.isEmpty(statusList)) {
                    CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get("status"));
                    for(String status : statusList) {
                        in.value(status);
                    }
                    predicates.add(in);
                }
                Predicate[] pre = new Predicate[predicates.size()];
                criteriaQuery.where(predicates.toArray(pre));
                return criteriaQuery.getRestriction();
            }
        };
        Page<CCNavEntity> navEntitiesPage = navDAO.findAll(specification, pageable);
        List<CTCNavResponseVO> navResponseVOList = new ArrayList<>();
        Map<Long, CCNavPathEntity> pathMap = pathService.getAllPathMap();
        if (navEntitiesPage != null && navEntitiesPage.getTotalElements() > 0) {
            List<CCNavEntity> navEntities = navEntitiesPage.getContent();
            for (CCNavEntity nav : navEntities) {
                Long navPathId = nav.getPathId();
                CTCNavResponseVO navResponseVO = convertNavResponseVO(nav);
                CCNavPathEntity pathEntity = pathMap.get(navPathId);
                if (navResponseVO != null && pathEntity != null) {
                    navResponseVO.setPathName(pathEntity.getName());
                }
                navResponseVOList.add(navResponseVO);
            }
        }
        return PAIPageResponseBeanUtil.success(pageNo,
                                           pageSize,
                                           navEntitiesPage.getTotalElements(),
                                           navResponseVOList);
    }

    private CTCNavResponseVO convertNavResponseVO(CCNavEntity nav) {
        CTCNavResponseVO navResponseVO = new CTCNavResponseVO();
        BeanUtils.copyProperties(nav, navResponseVO);
        return navResponseVO;
    }

    /***
     * 构建排序规则
     * @return
     */
    private Sort buildQueryOrderCondition() {
        List<Sort.Order> orderList = new ArrayList<>();
        // 默认按发布时间按 > 创建时间排序
        Sort.Order order1 = new Sort.Order(Sort.Direction.DESC, "score");
        Sort.Order order2 = new Sort.Order(Sort.Direction.ASC, "id");
        orderList.add(order1);
        orderList.add(order2);
        Sort sort = Sort.by(orderList);
        return sort;
    }

    private CCNavEntity convertNavEntity(CCNavRequestVO vo, String operator) {
        CCNavEntity navEntity;
        Date now = new Date();
        if (vo.getId() != null) {
            navEntity = navDAO.findAllById(vo.getId());
            Assert.isTrue(navEntity != null, "修改失败：导航不存在！");
        } else {
            navEntity = new CCNavEntity();
            navEntity.setCreateBy(operator);
            navEntity.setCreateDate(now);
            navEntity.setStatus(CommonStatusEnum.NEW.getStatus());
        }
        navEntity.setPathId(vo.getPathId());
        navEntity.setIcon(vo.getIcon());
        navEntity.setName(vo.getName());
        navEntity.setUrl(vo.getUrl());
        navEntity.setSummary(vo.getSummary());
        navEntity.setScore(vo.getScore());
        navEntity.setUpdateBy(operator);
        navEntity.setUpdateDate(now);
        return navEntity;
    }
}
